﻿/* ----------------------------------------------------------------------------
 * Copyright (c) Rob Ashton 2009
 *
 * This source code is subject to terms and conditions of the Microsoft Public 
 * License (Ms-PL).
 * 
 * By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * To request a copy of the Microsoft Public License, send a request by email
 * to license@mvcex.com
 *
 * This notice must not be removed from this software.
 * ---------------------------------------------------------------------------- */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Web.Mvc;

using MvcEx.Controllers;

namespace MvcEx.Tests
{
    [TestFixture]
    public class IntegrationTests
    {
        private IMvcExApplication mApplication;
        private MvcExDefaultApplicationConfigurationSelector mConfigSelector;

        [SetUp]
        public void initialise_application()
        {
            mApplication = MvcExApplication.Create("data\\IntegrationTests");
            mConfigSelector = new MvcExDefaultApplicationConfigurationSelector();
            mConfigSelector.DefaultConfiguration = "customerone";
            mApplication.SetConfigurationSelector(mConfigSelector);
        }

        [TearDown]
        public void shutdown_application()
        {
            mApplication = null;
        }

        [Test]
        public void request_valid_controller()
        {
            IController controller = mApplication.ControllerFactory.CreateController(
                 null,
                 "IntegrationOne");

            Assert.NotNull(controller);
        }

        [Test]
        public void request_invalid_controller()
        {
            IController controller = mApplication.ControllerFactory.CreateController(
            null,
            "NotAValidController");

            Assert.Null(controller);
        }

        [Test]
        public void request_controller_and_reset_controllerfactory()
        {
            IController controllerOne = mApplication.ControllerFactory.CreateController(
               null,
               "IntegrationOne");

            Assert.NotNull(controllerOne);

            // Force a reload the application configuration
            mApplication.Reload();

            IController controllerTwo = mApplication.ControllerFactory.CreateController(
               null,
               "IntegrationOne");

            Assert.NotNull(controllerTwo);

            Type typeOne = controllerOne.GetType();
            Type typeTwo = controllerTwo.GetType();

            // By resetting the configuration, the builders should have been flushed
            // And even though we're requesting a controller from the same configuration
            // And same controller - it should be a new type because we've lost the old one
            Assert.AreNotEqual(typeOne, typeTwo);
        }

        [Test]
        public void request_controller_and_change_configuration()
        {
            IController controllerOne = mApplication.ControllerFactory.CreateController(
                null,
                "IntegrationOne");

            mConfigSelector.DefaultConfiguration = "customertwo";

            IController controllerTwo = mApplication.ControllerFactory.CreateController(
               null,
               "IntegrationOne");

            mConfigSelector.DefaultConfiguration = "customerone";

            IController controllerThree = mApplication.ControllerFactory.CreateController(
                null,
                "IntegrationOne");
            
            Assert.NotNull(controllerOne);
            Assert.NotNull(controllerTwo);

            Type typeOne = controllerOne.GetType();
            Type typeTwo = controllerTwo.GetType();
            Type typeThree = controllerThree.GetType();

            // These should be separate types because they're from different configurations
            Assert.AreNotEqual(typeOne, typeTwo);

            // However, these should be the same because they're from the same configuration
            // Despite switching configuration
            Assert.AreEqual(typeOne, typeThree);
        }

        [MvcExActionContainer("IntegrationOne")]
        public class BasicActionContainer : MvcExActionContainer
        {
            public ActionResult Index()
            {
                return View();
            }
        }
    }
}
